﻿using System.Collections;
using System.Data;

namespace WinServiceProject
{
    using System;
    using System.IO;

    class WinService : System.ServiceProcess.ServiceBase
    {
        System.Timers.Timer testTimer = new System.Timers.Timer();

        //TODO:This values must be set dynamically not statically
        int _InMorning = 1;
        int _InSpecialCustomerVendor = 2;
        int _InSpecialPersonal = 3;
        int _InSpecialGenDoctor = 4;
        int _InSpecialSpeDoctor = 5;
        int _InLunch = 6;
        int _OutLunch = 7;
        int _OutSpecialCustomerVendor = 8;
        int _OutSpecialPersonal = 9;
        int _OutSpecialGenDoctor = 10;
        int _OutSpecialSpeDoctor = 11;
        int _OutExit = 12;

        // The main entry point for the process
        static void Main()
        {
            System.ServiceProcess.ServiceBase[] ServicesToRun;
            ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WinService() };
            System.ServiceProcess.ServiceBase.Run(ServicesToRun);
        }
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.ServiceName = "TCCalculatorService";
        }
        private void TimerJob(object sender, System.Timers.ElapsedEventArgs e)
        {
            if(!System.IO.Directory.Exists(folderPath))
                System.IO.Directory.CreateDirectory(folderPath);

            FileStream fs = new FileStream(folderPath + "\\TCCalculatorService.txt", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter m_streamWriter = new StreamWriter(fs);
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamWriter.WriteLine(" TCCalculatorService: Service Started at " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + "\n");
            m_streamWriter.Flush();
            m_streamWriter.Close();
            StartJob();
        }
        private string folderPath = @"c:\temp";
        /// <summary>
        /// Set things in motion so your service can do its work.
        /// </summary>
        protected override void OnStart(string[] args)
        {
            testTimer.Enabled = true;
            testTimer.Interval = 1000 * 60 * 10;//10 minutes interval
            testTimer.Elapsed += new System.Timers.ElapsedEventHandler(TimerJob);

            testTimer.Start();
        }
        /// <summary>
        /// Stop this service.
        /// </summary>
        protected override void OnStop()
        {
            FileStream fs = new FileStream(folderPath + "\\TCCalculatorService.txt", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter m_streamWriter = new StreamWriter(fs);
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamWriter.WriteLine(" TCCalculatorService: Service Stopped at " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString() + "\n");
            m_streamWriter.Flush();
            m_streamWriter.Close();
        }

        //The job1 starts on application loading.
        //It calculates the employees labour time per day
        //and writes the result to the db.
        private void StartJob()
        {
            try
            {
                //load action flows
                DataSet actionFlowDS = null;
                String sql = "SELECT * from dbo.ActionFlow";
                actionFlowDS = DB.Sorgula(sql, "");

                if (actionFlowDS == null)
                {
                    LogJobStatus(1, DateTime.Now, 0, "Could not retrieve data from ActionFlow table");
                    return;
                }

                sql = "SELECT MAX(LastProcessTime) FROM JobLog WHERE IsSuccessful = 1";
                DataSet ds = DB.Sorgula(sql, "StartJob1");
                if (ds == null)
                {
                    LogJobStatus(1, DateTime.Now, 0, "Could not retrieve data from JobLog table");
                    return;
                }

                //get appropriate start date for searching EmployeeActions table
                DateTime maxDate = Utility.GetMinDate();
                if (!ds.Tables[0].Rows[0][0].Equals(DBNull.Value))
                {
                    maxDate = Convert.ToDateTime(ds.Tables[0].Rows[0][0].ToString());
                }
                else//this is job's first time running
                {
                    sql = "SELECT MIN(ActionTime) FROM EmployeeActions";
                    ds = DB.Sorgula(sql, "StartJob1");
                    if (ds == null)
                    {
                        LogJobStatus(1, DateTime.Now, 0, "Could not retrieve data from JobLog table");
                        return;
                    }
                    if (!ds.Tables[0].Rows[0][0].Equals(DBNull.Value))
                    {
                        maxDate = Convert.ToDateTime(ds.Tables[0].Rows[0][0].ToString());
                    }
                    else//There is no data in table
                    {
                        LogJobStatus(1, DateTime.Now, 0, "There is no data in EmployeeActions table");
                        return;
                    }
                }

                sql = "SELECT * FROM Employees WHERE IsDeleted = 0";
                DataSet employeeDS = DB.Sorgula(sql, "StartJob1");
                if (employeeDS == null)
                {
                    LogJobStatus(1, DateTime.Now, 0, "Could not retrieve data from Employees table");
                    return;
                }
                if (employeeDS.Tables[0].Rows.Count == 0)
                {
                    LogJobStatus(1, DateTime.Now, 0, "There is no employee in Employees table");
                    return;
                }

                TimeSpan f_pl_s = new TimeSpan();//Full Day Pre Labour Start Time 
                TimeSpan f_pl_e = new TimeSpan();//Full Day Pre Labour End Time 
                TimeSpan f_i_s = new TimeSpan();//Full Day Flexible Entrance Start Time 
                TimeSpan f_i_e = new TimeSpan();//Full Day Flexible Entrance End Time 
                TimeSpan f_m_s = new TimeSpan();//Full Day Morning Start Time 
                TimeSpan f_m_e = new TimeSpan();//Full Day Morning End Time 
                TimeSpan f_l_s = new TimeSpan();//Full Day Flexible Entrance Lunch Start Time 
                TimeSpan f_l_e = new TimeSpan();//Full Day Flexible Entrance Lunch End Time 
                TimeSpan f_a_s = new TimeSpan();//Full Day Afternoon Labour Start Time 
                TimeSpan f_a_e = new TimeSpan();//Full Day Afternoon Labour End Time 
                TimeSpan f_o_s = new TimeSpan();//Full Day Flexible Out Start Time 
                TimeSpan f_o_e = new TimeSpan();//Full Day Flexible Out End Time 
                TimeSpan f_al_s = new TimeSpan();//Full Day After Labour Start Time 
                TimeSpan f_al_e = new TimeSpan();//Full Day After Labour End Time 

                TimeSpan h_pl_s = new TimeSpan();//Half Day Pre Labour Start Time 
                TimeSpan h_pl_e = new TimeSpan();//Half Day Pre Labour End Time 
                TimeSpan h_i_s = new TimeSpan();//Half Day Flexible Entrance Start Time 
                TimeSpan h_i_e = new TimeSpan();//Half Day Flexible Entrance End Time 
                TimeSpan h_m_s = new TimeSpan();//Half Day Morning Start Time 
                TimeSpan h_m_e = new TimeSpan();//Half Day Morning End Time 
                TimeSpan h_lo_s = new TimeSpan();//Half Day Flexible Entrance Lunch and flexible out Start Time 
                TimeSpan h_lo_e = new TimeSpan();//Half Day Flexible Entrance Lunch and flexible out End Time 
                TimeSpan h_a_s = new TimeSpan();//Half Day Afternoon Labour Start Time 
                TimeSpan h_a_e = new TimeSpan();//Half Day Afternoon Labour End Time 
                TimeSpan h_o_s = new TimeSpan();//Half Day Flexible Out Start Time 
                TimeSpan h_o_e = new TimeSpan();//Half Day Flexible Out End Time 
                TimeSpan h_l_s = new TimeSpan();//Half Day After Labour Start Time 
                TimeSpan h_l_e = new TimeSpan();//Half Day After Labour End Time 


                sql = "SELECT * FROM TimeBlocks";
                DataSet timeBlockDS = DB.Sorgula(sql, "StartJob1");
                if (timeBlockDS == null)
                {
                    LogJobStatus(1, DateTime.Now, 0, "Could not retrieve data from TimeBlocks table");
                    return;
                }
                foreach (DataRow dr in timeBlockDS.Tables[0].Rows)
                {
                    if (dr["IsFull"].ToString().Equals("True"))
                    {
                        if (dr["TimeCode"].ToString().Equals("PL"))
                        {
                            f_pl_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_pl_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("I"))
                        {
                            f_i_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_i_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("M"))
                        {
                            f_m_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_m_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("L"))
                        {
                            f_l_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_l_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("A"))
                        {
                            f_a_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_a_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("O"))
                        {
                            f_o_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_o_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("AL"))
                        {
                            f_al_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            f_al_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                    }
                    else
                    {
                        if (dr["TimeCode"].ToString().Equals("PL"))
                        {
                            h_pl_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_pl_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("I"))
                        {
                            h_i_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_i_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("M"))
                        {
                            h_m_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_m_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("LO"))
                        {
                            h_lo_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_lo_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("A"))
                        {
                            h_a_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_a_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("O"))
                        {
                            h_o_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_o_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                        else if (dr["TimeCode"].ToString().Equals("L"))
                        {
                            h_l_s = TimeSpan.Parse(dr["TimePeriodFrom"].ToString());
                            h_l_e = TimeSpan.Parse(dr["TimePeriodTo"].ToString());
                        }
                    }
                }

                DateTime jobMaxDate = Utility.GetMinDate();
                //start calculating
                for (DateTime date = maxDate; date.CompareTo(DateTime.Now) <= 0; date = date.AddDays(1))
                {
                    //check DateOfDays for related date 
                    //if the related date is not defined return
                    sql = "SELECT * FROM DateOfDays WHERE DateOfDay = '" + String.Format(@"{0:yyyy-MM-dd 00:00:00}", date) + "'";
                    ds = DB.Sorgula(sql, "StartJob1");
                    if (ds != null && ds.Tables[0].Rows.Count != 1)
                    {
                        LogJobStatus(1, DateTime.Now, 0, String.Format(@"{0:yyyy-MM-dd}", date) + " is not defined in DateOfDays table");
                        return;
                    }
                    jobMaxDate = Utility.GetOnlyDate(date);
                    ArrayList employees = new ArrayList();
                    foreach (DataRow edr in employeeDS.Tables[0].Rows)
                    {
                        String currentEmployee = edr["EmployeeID"].ToString();
                        DateTime hireDate = Convert.ToDateTime(edr["HireDate"]);

                        if (hireDate.CompareTo(date) > 0)
                        {
                            continue;
                        }
                        //Check if employee is on vacation on that date

                        sql = "SELECT * FROM EmployeeVacations WHERE EmployeeID = " + currentEmployee + " AND VacationDate = '" + String.Format("{0:yyyy-MM-dd}", date) + "'";
                        ds = DB.Sorgula(sql, "StartJob1");
                        if (ds == null)
                        {
                            LogJobStatus(1, date, 0, "Could not retrieve data from EmployeeVacations table");
                            return;
                        }
                        if (ds.Tables[0].Rows.Count > 0)//employee is on vacation
                        {
                            continue;
                        }
                        sql = @"SELECT * FROM EmployeeActions WHERE ActionTime BETWEEN '" + String.Format(@"{0:yyyy-MM-dd 00:00:00}", date) +
                              @"' AND '" + String.Format(@"{0:yyyy-MM-dd 23:59:59}", date) + "' AND EmployeeID = " + currentEmployee + " order by cast(floor(cast(ActionTime as float)) as datetime) asc, ActionTime asc;";
                        ds = DB.Sorgula(sql, "StartJob1");
                        if (ds == null)
                        {
                            LogJobStatus(1, date, 0, "Could not retrieve data from EmployeeActions table");
                            return;
                        }
                        if (ds.Tables[0].Rows.Count > 0)
                        {
                            foreach (DataRow dr in ds.Tables[0].Rows)
                            {
                                String currentDate = Convert.ToDateTime(dr["ActionTime"]).ToShortDateString();
                                if (Convert.ToDateTime(dr["ActionTime"]).CompareTo(jobMaxDate) > 0)
                                    jobMaxDate = Convert.ToDateTime(dr["ActionTime"]);
                                Employee employee = null;
                                DailyAction dailyAction = null;
                                foreach (Employee e in employees)
                                {
                                    if (e.employeeID.ToString().Equals(currentEmployee))
                                    {
                                        employee = e;
                                        break;
                                    }
                                }
                                if (employee != null)
                                {
                                    foreach (DailyAction da in employee.dailyActions)
                                    {
                                        if (currentDate.Equals(da.date.ToShortDateString()))
                                        {
                                            dailyAction = da;
                                            break;
                                        }
                                    }
                                    if (dailyAction != null)
                                    {
                                        Action action = new Action();
                                        action.employeeActionID = Convert.ToInt32(dr["EmployeeActionID"]);
                                        action.actionID = Convert.ToInt32(dr["ActionID"]);
                                        action.actionTime = Convert.ToDateTime(dr["ActionTime"]);
                                        dailyAction.actions.Add(action);
                                    }
                                    else
                                    {
                                        Action action = new Action();
                                        action.employeeActionID = Convert.ToInt32(dr["EmployeeActionID"]);
                                        action.actionID = Convert.ToInt32(dr["ActionID"]);
                                        action.actionTime = Convert.ToDateTime(dr["ActionTime"]);
                                        dailyAction = new DailyAction();
                                        dailyAction.date = Utility.GetOnlyDate(Convert.ToDateTime(dr["ActionTime"]));
                                        dailyAction.actions = new ArrayList();
                                        dailyAction.actions.Add(action);
                                        employee.dailyActions.Add(dailyAction);
                                    }
                                }
                                else
                                {
                                    employee = new Employee();
                                    employee.employeeID = Convert.ToInt32(currentEmployee);
                                    employee.dailyActions = new ArrayList();


                                    Action action = new Action();
                                    action.employeeActionID = Convert.ToInt32(dr["EmployeeActionID"]);
                                    action.actionID = Convert.ToInt32(dr["ActionID"]);
                                    action.actionTime = Convert.ToDateTime(dr["ActionTime"]);
                                    dailyAction = new DailyAction();
                                    dailyAction.date = Utility.GetOnlyDate(Convert.ToDateTime(dr["ActionTime"]));
                                    dailyAction.actions = new ArrayList();
                                    dailyAction.actions.Add(action);
                                    employee.dailyActions.Add(dailyAction);
                                    employees.Add(employee);
                                }
                            }

                            if (employees.Count > 0)
                            {
                                foreach (Employee emp in employees)
                                {
                                    foreach (DailyAction da in emp.dailyActions)
                                    {
                                        EmployeeDailyAction eda = new EmployeeDailyAction();
                                        eda.employeeID = emp.employeeID;
                                        eda.actionDate = da.date;
                                        sql = @"SELECT * FROM EmployeeDailyActions where ActionDate = '" + String.Format(@"{0:yyyy-MM-dd 00:00:00}", da.date) + "' AND EmployeeID = " + emp.employeeID;
                                        DataSet dataSet = DB.Sorgula(sql, "");
                                        bool dailyActionExits = true;
                                        bool isOperatorAdmin = false;
                                        if (dataSet.Tables[0].Rows.Count == 0)
                                        {
                                            dailyActionExits = false;
                                        }
                                        else
                                        {
                                            if (Convert.ToInt32(dataSet.Tables[0].Rows[0]["Operator"]) == 0)
                                            {
                                                isOperatorAdmin = false;
                                            }
                                        }
                                        int s = 0;
                                        foreach (Action action in da.actions)
                                        {
                                            if (s == 0)
                                            {
                                                eda.move1ActionID = action.actionID;
                                                eda.move1ActionTime = action.actionTime;
                                            }
                                            else if (s == 1)
                                            {
                                                eda.move2ActionID = action.actionID;
                                                eda.move2ActionTime = action.actionTime;
                                            }
                                            else if (s == 2)
                                            {
                                                eda.move3ActionID = action.actionID;
                                                eda.move3ActionTime = action.actionTime;
                                            }
                                            else if (s == 3)
                                            {
                                                eda.move4ActionID = action.actionID;
                                                eda.move4ActionTime = action.actionTime;
                                            }
                                            else if (s == 4)
                                            {
                                                eda.move5ActionID = action.actionID;
                                                eda.move5ActionTime = action.actionTime;
                                            }
                                            else if (s == 5)
                                            {
                                                eda.move6ActionID = action.actionID;
                                                eda.move6ActionTime = action.actionTime;
                                            }
                                            else if (s == 6)
                                            {
                                                eda.move7ActionID = action.actionID;
                                                eda.move7ActionTime = action.actionTime;
                                            }
                                            else if (s == 7)
                                            {
                                                eda.move8ActionID = action.actionID;
                                                eda.move8ActionTime = action.actionTime;
                                            }
                                            s++;
                                        }
                                        //calculate labour time
                                        if (da.actions.Count % 2 == 0)
                                        {
                                            if (da.actions.Count == 4)//suppose that 1)In morning 2)out lunch 3)in lunch 4)out exit
                                            {
                                                if (((Action)da.actions[0]).actionID == _InMorning &&
                                                   ((Action)da.actions[1]).actionID == _OutLunch &&
                                                   ((Action)da.actions[2]).actionID == _InLunch &&
                                                   ((Action)da.actions[3]).actionID == _OutExit)
                                                {
                                                    Action inMorningAction = (Action)da.actions[0];
                                                    Action outLunchAction = (Action)da.actions[1];
                                                    Action inLunchAction = (Action)da.actions[2];
                                                    Action outExitAction = (Action)da.actions[3];

                                                    TimeSpan el = new TimeSpan(), l = new TimeSpan();
                                                    if (inMorningAction.actionTime.TimeOfDay < f_i_s)
                                                    {
                                                        el = f_i_s.Subtract(inMorningAction.actionTime.TimeOfDay);
                                                        l = outLunchAction.actionTime.TimeOfDay.Subtract(f_i_s);
                                                    }
                                                    else
                                                    {
                                                        l = outLunchAction.actionTime.TimeOfDay.Subtract(inMorningAction.actionTime.TimeOfDay);
                                                    }

                                                    if (outExitAction.actionTime.TimeOfDay > f_al_s)
                                                    {
                                                        el = el.Add(outExitAction.actionTime.TimeOfDay.Subtract(f_al_s));
                                                        l = l.Add(f_al_s.Subtract(inLunchAction.actionTime.TimeOfDay));
                                                    }
                                                    else
                                                    {
                                                        l = l.Add(outExitAction.actionTime.TimeOfDay.Subtract(inLunchAction.actionTime.TimeOfDay));
                                                    }


                                                    /*TimeSpan beforeLunch = outLunchAction.actionTime.Subtract(inMorningAction.actionTime);
                                                    TimeSpan afterLunch = outExitAction.actionTime.Subtract(inLunchAction.actionTime);
                                                    TimeSpan totalLabour = beforeLunch.Add(afterLunch);
                                                    int labour = totalLabour.Hours * 60 + totalLabour.Minutes;
                                                    eda.labour = labour;*/
                                                    eda.labour = l.Hours * 60 + l.Minutes;
                                                    eda.eLabour = el.Hours * 60 + el.Minutes;
                                                }
                                            }
                                            else if (da.actions.Count == 6 || da.actions.Count == 8)
                                            {
                                                if (((Action)da.actions[0]).actionID == _InMorning && ((Action)da.actions[da.actions.Count - 1]).actionID == _OutExit)
                                                {

                                                    bool isLegal = true;
                                                    //check actionflows
                                                    for (int j = 0; j <= (da.actions.Count - 1); j++)
                                                    {
                                                        int actionId = ((Action)da.actions[j]).actionID;
                                                        //if it is not the last action.
                                                        //because we check the last action on previous step
                                                        if (j != (da.actions.Count - 1))
                                                        {
                                                            int nextActionId = ((Action)da.actions[j + 1]).actionID;
                                                            int len = actionFlowDS.Tables[0].Select("FirstActionId = " + actionId + " AND NextActionId = " + nextActionId).Length;
                                                            if (len == 0)//it is not a legal action. because the action pair not defined.
                                                            {
                                                                //Daily actions are not legal
                                                                isLegal = false;
                                                                break;
                                                            }
                                                        }
                                                    }
                                                    if (isLegal)
                                                    {
                                                        DateTime inMorning = DateTime.MinValue, inPersonal = DateTime.MinValue, inGenDoc = DateTime.MinValue, inSpeDoc = DateTime.MinValue, inCusVen = DateTime.MinValue, inLunch = DateTime.MinValue;
                                                        DateTime outExit = DateTime.MinValue, outPersonal = DateTime.MinValue, outGenDoc = DateTime.MinValue, outSpeDoc = DateTime.MinValue, outCusVen = DateTime.MinValue, outLunch = DateTime.MinValue;


                                                        foreach (Action action in da.actions)
                                                        {
                                                            if (action.actionID == _InMorning)
                                                                inMorning = action.actionTime;
                                                            else if (action.actionID == _InSpecialPersonal)
                                                                inPersonal = action.actionTime;
                                                            else if (action.actionID == _InSpecialGenDoctor)
                                                                inGenDoc = action.actionTime;
                                                            else if (action.actionID == _InSpecialSpeDoctor)
                                                                inSpeDoc = action.actionTime;
                                                            else if (action.actionID == _InSpecialCustomerVendor)
                                                                inCusVen = action.actionTime;
                                                            else if (action.actionID == _InLunch)
                                                                inLunch = action.actionTime;
                                                            else if (action.actionID == _OutExit)
                                                                outExit = action.actionTime;
                                                            else if (action.actionID == _OutSpecialPersonal)
                                                                outPersonal = action.actionTime;
                                                            else if (action.actionID == _OutSpecialGenDoctor)
                                                                outGenDoc = action.actionTime;
                                                            else if (action.actionID == _OutSpecialSpeDoctor)
                                                                outSpeDoc = action.actionTime;
                                                            else if (action.actionID == _OutSpecialCustomerVendor)
                                                                outCusVen = action.actionTime;
                                                            else if (action.actionID == _OutLunch)
                                                                outLunch = action.actionTime;


                                                        }

                                                        //lunch actions must exists
                                                        if (inLunch.CompareTo(DateTime.MinValue) != 0 && outLunch.CompareTo(DateTime.MinValue) != 0)
                                                        {
                                                            //TimeSpan lunch = inLunch.Subtract(outLunch);
                                                            TimeSpan inOut = outExit.Subtract(inMorning);
                                                            TimeSpan genDoc = inGenDoc.Subtract(outGenDoc);
                                                            TimeSpan speDoc = inSpeDoc.Subtract(outSpeDoc);
                                                            TimeSpan perIss = inPersonal.Subtract(outPersonal);
                                                            TimeSpan cusVen = inCusVen.Subtract(outCusVen);

                                                            TimeSpan el = new TimeSpan(), l = new TimeSpan();
                                                            if (inMorning.TimeOfDay < f_i_s)
                                                            {
                                                                el = f_i_s.Subtract(inMorning.TimeOfDay);
                                                                l = outLunch.TimeOfDay.Subtract(f_i_s);
                                                            }
                                                            else
                                                            {
                                                                l = outLunch.TimeOfDay.Subtract(inMorning.TimeOfDay);
                                                            }

                                                            if (outExit.TimeOfDay > f_al_s)
                                                            {
                                                                el = el.Add(outExit.TimeOfDay.Subtract(f_al_s));
                                                                l = l.Add(f_al_s.Subtract(inLunch.TimeOfDay));
                                                            }
                                                            else
                                                            {
                                                                l = l.Add(outExit.TimeOfDay.Subtract(inLunch.TimeOfDay));
                                                            }

                                                            l = l.Subtract(genDoc).Subtract(speDoc).Subtract(perIss);

                                                            eda.labour = l.Hours * 60 + l.Minutes;
                                                            eda.eLabour = el.Hours * 60 + el.Minutes;
                                                            eda.genDoc = genDoc.Hours * 60 + genDoc.Minutes;
                                                            eda.speDoc = speDoc.Hours * 60 + speDoc.Minutes;
                                                            eda.perIss = perIss.Hours * 60 + perIss.Minutes;
                                                            eda.cusVen = cusVen.Hours * 60 + cusVen.Minutes;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        ProcessEmployeeDailyAction(eda, dailyActionExits, isOperatorAdmin);
                                    }
                                }
                            }
                        }
                    }
                    LogJobStatus(1, jobMaxDate, 1, "");
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                LogJobStatus(1, DateTime.Now, 0, ex.StackTrace);
            }
        }

        private void LogJobStatus(int jobID, DateTime time, int success, String description)
        {
            description = Utility.InputFilter(description);
            if (description.Length > 500)
                description = description.Substring(0, 500);
            string sql = @"INSERT INTO JobLog(JobID, LastProcessTime, IsSuccessful, Description) VALUES(" +
                jobID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", time) + "', " + success + ", '" + description + "')";
            DB.Uygula(sql, "LogJobStatus");
        }

        private void ProcessEmployeeDailyAction(EmployeeDailyAction eda, bool dailyActionExits, bool isOperatorAdmin)
        {
            String sql = @"";
            if (dailyActionExits)
            {
                sql = @"UPDATE EmployeeDailyActions SET Move1ActionID = " + eda.move1ActionID + ", Move1ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move1ActionTime) + "'";
                if (eda.move2ActionID != -1)
                {
                    sql += @", Move2ActionID = " + eda.move2ActionID + ", Move2ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move2ActionTime) + "'";
                }
                if (eda.move3ActionID != -1)
                {
                    sql += @", Move3ActionID = " + eda.move3ActionID + ", Move3ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move3ActionTime) + "'";
                }
                if (eda.move4ActionID != -1)
                {
                    sql += @", Move4ActionID = " + eda.move4ActionID + ", Move4ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move4ActionTime) + "'";
                }
                if (eda.move5ActionID != -1)
                {
                    sql += @", Move5ActionID = " + eda.move5ActionID + ", Move5ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move5ActionTime) + "'";
                }
                if (eda.move6ActionID != -1)
                {
                    sql += @", Move6ActionID = " + eda.move6ActionID + ", Move6ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move6ActionTime) + "'";
                }
                if (eda.move7ActionID != -1)
                {
                    sql += @", Move7ActionID = " + eda.move7ActionID + ", Move7ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move7ActionTime) + "'";
                }
                if (eda.move8ActionID != -1)
                {
                    sql += @", Move8ActionID = " + eda.move8ActionID + ", Move8ActionTime = '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move8ActionTime) + "'";
                }

                if (eda.labour != 0)
                {
                    if (!isOperatorAdmin)
                    {
                        sql += ", Labour = " + eda.labour;
                    }
                }
                if (eda.eLabour != 0)
                {
                    if (!isOperatorAdmin)
                    {
                        sql += ", ELabour = " + eda.eLabour;
                    }
                }
                if (eda.genDoc != 0)
                {
                    sql += ", GenDoc = " + eda.genDoc;
                }
                if (eda.speDoc != 0)
                {
                    sql += ", SpeDoc = " + eda.speDoc;
                }
                if (eda.perIss != 0)
                {
                    sql += ", PerIss = " + eda.perIss;
                }
                if (eda.cusVen != 0)
                {
                    sql += ", CusVen = " + eda.cusVen;
                }

                sql += " WHERE EmployeeID = " + eda.employeeID + " AND ActionDate = '" + String.Format(@"{0:yyyy-MM-dd 00:00:00}", eda.actionDate) + "'";
                DB.Uygula(sql, "ProcessEmployeeDailyAction");
            }
            else
            {
                String sql1 = @"INSERT INTO EmployeeDailyActions(EmployeeID, ActionDate, Move1ActionID, Move1ActionTime";
                String sql2 = @") VALUES(" + eda.employeeID + ", '" + String.Format(@"{0:yyyy-MM-dd 00:00:00}", eda.actionDate) + "', " + eda.move1ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move1ActionTime) + "'";


                if (eda.move2ActionID != -1)
                {
                    sql1 += @", Move2ActionID, Move2ActionTime";
                    sql2 += @", " + eda.move2ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move2ActionTime) + "'";
                }
                if (eda.move3ActionID != -1)
                {
                    sql1 += @", Move3ActionID, Move3ActionTime";
                    sql2 += @", " + eda.move3ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move3ActionTime) + "'";
                }
                if (eda.move4ActionID != -1)
                {
                    sql1 += @", Move4ActionID, Move4ActionTime";
                    sql2 += @", " + eda.move4ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move4ActionTime) + "'";
                }
                if (eda.move5ActionID != -1)
                {
                    sql1 += @", Move5ActionID, Move5ActionTime";
                    sql2 += @", " + eda.move5ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move5ActionTime) + "'";
                }
                if (eda.move6ActionID != -1)
                {
                    sql1 += @", Move6ActionID, Move6ActionTime";
                    sql2 += @", " + eda.move6ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move6ActionTime) + "'";
                }
                if (eda.move7ActionID != -1)
                {
                    sql1 += @", Move7ActionID, Move7ActionTime";
                    sql2 += @", " + eda.move7ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move7ActionTime) + "'";
                }
                if (eda.move8ActionID != -1)
                {
                    sql1 += @", Move8ActionID, Move8ActionTime";
                    sql2 += @", " + eda.move8ActionID + ", '" + String.Format(@"{0:yyyy-MM-dd HH:mm:ss}", eda.move8ActionTime) + "'";
                }

                if (eda.labour != 0)
                {
                    sql1 += @", Labour";
                    sql2 += @", " + eda.labour;
                }
                if (eda.eLabour != 0)
                {
                    sql1 += @", ELabour";
                    sql2 += @", " + eda.eLabour;
                }
                if (eda.genDoc != 0)
                {
                    sql1 += @", GenDoc";
                    sql2 += @", " + eda.genDoc;
                }
                if (eda.speDoc != 0)
                {
                    sql1 += @", SpeDoc";
                    sql2 += @", " + eda.speDoc;
                }
                if (eda.perIss != 0)
                {
                    sql1 += @", PerIss";
                    sql2 += @", " + eda.perIss;
                }
                if (eda.cusVen != 0)
                {
                    sql1 += @", CusVen";
                    sql2 += @", " + eda.cusVen;
                }
                sql = sql1 + sql2 + ")";
                DB.Uygula(sql, "ProcessEmployeeDailyAction");
            }
        }


    }

    class Employee
    {
        public int employeeID;
        public ArrayList dailyActions;
    }

    class DailyAction
    {
        public DateTime date;
        public ArrayList actions;
    }

    class Action
    {
        public int actionID;
        public int employeeActionID;
        public DateTime actionTime;
    }

    class EmployeeDailyAction
    {
        public int employeeID;
        public DateTime actionDate;
        public int move1ActionID;
        public DateTime move1ActionTime;
        public int move2ActionID;
        public DateTime move2ActionTime;
        public int move3ActionID;
        public DateTime move3ActionTime;
        public int move4ActionID;
        public DateTime move4ActionTime;
        public int move5ActionID;
        public DateTime move5ActionTime;
        public int move6ActionID;
        public DateTime move6ActionTime;
        public int move7ActionID;
        public DateTime move7ActionTime;
        public int move8ActionID;
        public DateTime move8ActionTime;
        public int labour;
        public int eLabour;
        public int genDoc;
        public int speDoc;
        public int cusVen;
        public int perIss;

        public EmployeeDailyAction()
        {
            employeeID = -1;
            actionDate = DateTime.MinValue;
            move1ActionID = -1;
            move1ActionTime = DateTime.MinValue;
            move2ActionID = -1;
            move2ActionTime = DateTime.MinValue;
            move3ActionID = -1;
            move3ActionTime = DateTime.MinValue;
            move4ActionID = -1;
            move4ActionTime = DateTime.MinValue;
            move5ActionID = -1;
            move5ActionTime = DateTime.MinValue;
            move6ActionID = -1;
            move6ActionTime = DateTime.MinValue;
            move7ActionID = -1;
            move7ActionTime = DateTime.MinValue;
            move8ActionID = -1;
            move8ActionTime = DateTime.MinValue;
            labour = 0;
            eLabour = 0;
            genDoc = 0;
            speDoc = 0;
            cusVen = 0;
            perIss = 0;
        }
    }
}